"use strict";

import { useMainDefaultIpc } from "./services/ipc-main";
import { app, session, ipcMain, dialog, shell } from "electron";
import InitWindow from "./services/window-manager";
import { useDisableButton } from "./hooks/disable-button-hook";
import { useProcessException } from "@main/hooks/exception-hook";
import { useMenu } from "@main/hooks/menu-hook";
import path from "path";
import fs from "fs";
import { exec, spawn } from "child_process";
function onAppReady() {
  const { disableF12 } = useDisableButton();
  const { renderProcessGone } = useProcessException();
  const { defaultIpc } = useMainDefaultIpc();
  const { creactMenu } = useMenu();
  disableF12();
  renderProcessGone();
  defaultIpc();
  creactMenu();
  new InitWindow().initWindow();
  if (process.env.NODE_ENV === "development") {
    const { VUEJS_DEVTOOLS } = require("electron-devtools-vendor");
    session.defaultSession.loadExtension(VUEJS_DEVTOOLS, {
      allowFileAccess: true,
    });
    console.log("已安装: vue-devtools");
  }
}

app.whenReady().then(onAppReady);
// 由于9.x版本问题，需要加入该配置关闭跨域问题
app.commandLine.appendSwitch("disable-features", "OutOfBlinkCors");

app.on("window-all-closed", () => {
  // 所有平台均为所有窗口关闭就退出软件
  app.quit();
});
app.on("browser-window-created", () => {
  console.log("window-created");
});
ipcMain.handle("select-folders", async () => {
  const result = await dialog.showOpenDialog({
    properties: ["openDirectory", "multiSelections"],
  });
  if (result.canceled) {
    return null;
  } else {
    return result.filePaths; // 返回选中的文件夹路径
  }
});
const executeCommand = (
  command: string, //命令
  folderPath: string, //路径
  useCmd: boolean, //是否唤醒cmd
  options = {}
) => {
  return new Promise((resolve, reject) => {
    if (useCmd) {
      // 使用spawn在新CMD窗口中执行命令
      const child = spawn("start", ["cmd", "/k", command], {
        cwd: folderPath,
        shell: true, // 使用shell选项以确保在CMD中执行
        ...options,
      });

      // 捕获子进程的输出
      let output = "";
      child.stdout.on("data", (data) => {
        output += data;
      });

      child.stderr.on("data", (data) => {
        output += data;
      });

      child.on("close", (code) => {
        if (code === 0) {
          resolve(output);
        } else {
          reject(`${code}\n${output}`);
        }
      });
    } else {
      // 使用exec在当前进程中执行命令
      exec(
        command,
        { cwd: folderPath, ...options },
        (error, stdout, stderr) => {
          if (error) {
            reject(`Error: ${stderr}`);
            return;
          }
          resolve(stdout);
        }
      );
    }
  });
};
ipcMain.handle(
  "execute-command",
  async (event, folderPath, command, useCmd) => {
    return await executeCommand(command, folderPath, useCmd);
  }
);
ipcMain.handle("read-all-folders", async (event, dirPath) => {
  // 定义递归读取文件夹的函数
  const readAllFolders = (dirPath: string, folders = []) => {
    const entries = fs.readdirSync(dirPath, { withFileTypes: true });

    entries.forEach((entry) => {
      const fullPath = path.join(dirPath, entry.name);

      if (entry.isDirectory()) {
        folders.push(fullPath);
        // readAllFolders(fullPath, folders); // 递归调用自身读取子文件夹
      }
    });

    return folders;
  };

  try {
    // 确保 dirPath 是有效的目录路径
    if (fs.existsSync(dirPath) && fs.lstatSync(dirPath).isDirectory()) {
      const folders = readAllFolders(dirPath);
      return folders; // 返回所有读取到的文件夹路径
    } else {
      throw new Error("Invalid directory path");
    }
  } catch (error) {
    throw error; // 如果发生错误，则抛出错误以便前端处理
  }
});
ipcMain.handle("open-url", async (event, url) => {
  try {
    await shell.openExternal(url);
  } catch (error) {
    // console.error("Failed to open URL:", error);
    throw error; // 将错误抛回给渲染进程以进行处理
  }
});
ipcMain.handle("get-node-list", async (event, useExec = false) => {
  return new Promise((resolve, reject) => {
    if (useExec) {
      // 使用 exec 方式
      exec("nvm list", (error, stdout, stderr) => {
        if (error) {
          reject(stderr || error.message);
          return;
        }
        resolve(stdout); // 返回命令的输出
      });
    } else {
      // 使用 spawn 方式
      const nvmList = spawn("nvm", ["list"], { shell: true });

      let output = "";

      // 实时处理标准输出的数据
      nvmList.stdout.on("data", (data) => {
        output += data.toString();
      });

      // 实时处理标准错误输出的数据
      nvmList.stderr.on("data", (data) => {});

      // 监听子进程关闭事件，确保命令执行完成
      nvmList.on("close", (code) => {
        if (code !== 0) {
          reject(code);
        } else {
          resolve(output); // 返回最终收集的所有输出
        }
      });
    }
  });
});
async function selectFiles() {
  const result = await dialog.showOpenDialog({
    title: "Select executable files or shortcuts",
    filters: [{ name: "Executable Files", extensions: ["exe", "lnk"] }],
    properties: ["openFile", "multiSelections"], // 允许多选
  });
  let selectedPaths: string[] = [];
  if (!result.canceled && result.filePaths.length > 0) {
    selectedPaths = result.filePaths; // 保存选定的路径
  }

  return selectedPaths;
}
ipcMain.handle("select-files", async () => {
  return await selectFiles();
});
function launchSavedFiles(selectedPaths: string[]) {
  if (selectedPaths.length === 0) {
    console.log("No paths to launch");
    return;
  }

  selectedPaths.forEach((filePath) => {
    if (filePath.endsWith(".lnk")) {
      // 如果是快捷方式，使用 start 命令
      spawn("cmd", ["/c", "start", "", filePath], { shell: true });
    } else if (filePath.endsWith(".exe")) {
      // 如果是 .exe 文件，直接启动
      spawn(filePath, [], { detached: true, stdio: "ignore" }).unref();
    }
  });
}

// 在主进程中设置一个 IPC 处理器来调用此方法
ipcMain.handle("launch-files", async (event, selectedPaths) => {
  launchSavedFiles(selectedPaths);
});

ipcMain.handle(
  "batchRenameFileIncrement",
  async (event, folderPath, renameRule, replaceExt = true) => {
    return new Promise((resolve, reject) => {
      try {
        const files = fs.readdirSync(folderPath);
        let counter = 1;

        // 使用正则提取规则中的文件名部分（忽略扩展名）
        const regex = /\$\{(\d+)\}/; // 匹配 `${数字}` 的形式
        const fileNamePart = renameRule.replace(/\$\{(\d+)\}/g, ""); // 去除 `${}` 里的数字，提取文件名部分
        // 替换 `${数字}` 为自增数字
        const match = regex.exec(renameRule);
        let incrementValue = "1";
        if (match && match[1]) {
          incrementValue = match[1]; // 获取自增位置的数字
          counter = +incrementValue;
        }

        // 遍历每个文件并重命名
        files.forEach((file) => {
          const fileExt = path.extname(file); // 获取文件扩展名
          if (fileExt) {
            let newFileName = renameRule;
            newFileName = renameRule.replace(
              `\${${incrementValue}}`,
              counter.toString()
            );
            // 处理扩展名替换
            if (replaceExt) {
              // 如果 replaceExt 为 true，需要替换扩展名
              const newExt = path.extname(renameRule); // 获取规则中的扩展名
              newFileName = newFileName.replace(fileExt, newExt); // 替换文件扩展名
            } else {
              // 如果 replaceExt 为 false，不替换扩展名
              newFileName = newFileName.replace(/\$\{(\d+)\}/g, "") + fileExt; // 保留原扩展名
            }

            const oldFilePath = path.join(folderPath, file);
            const newFilePath = path.join(folderPath, newFileName);

            // 确保新文件名没有覆盖现有文件
            if (fs.existsSync(newFilePath)) {
              reject(`文件已存在：${newFilePath}`);
              return;
            }

            // 重命名文件
            fs.renameSync(oldFilePath, newFilePath);
            counter++; // 自增数字
          }
        });

        resolve("批量自增命名成功！");
      } catch (error) {
        reject(`批量重命名失败：${error.message}`);
      }
    });
  }
);

ipcMain.handle(
  "batchRenameFileReplace",
  async (event, folderPath, renameRule, replaceExt = false) => {
    return new Promise((resolve, reject) => {
      try {
        const files = fs.readdirSync(folderPath);

        // 解析规则中的需要替换的部分
        const ruleParts = renameRule.match(/\$\{([^}]+)\}/g); // 获取规则中的 `${}` 部分

        // 如果规则部分不满足要求，返回错误
        if (!ruleParts || ruleParts.length !== 2) {
          reject(
            "替换规则格式不正确，必须包含两个替换部分！ " +
              JSON.stringify(ruleParts)
          );
          return;
        }

        const [searchStr, replaceStr] = ruleParts.map((part) =>
          part.replace(/\$\{|\}/g, "")
        ); // 提取规则中的 'png' 和 'jpg'

        // 遍历文件夹中的所有文件
        files.forEach((file) => {
          let fileExt = path.extname(file); // 获取文件扩展名
          let baseName = path.basename(file, fileExt); // 获取文件的基本名（去除扩展名）

          // 如果 replaceExt 为 true，首先处理扩展名
          if (replaceExt) {
            if (baseName.includes(searchStr)) {
              baseName = baseName.replace(searchStr, replaceStr);
            }
            if (fileExt.includes(searchStr)) {
              fileExt = fileExt.replace(searchStr, replaceStr); // 替换扩展名中的字符串
            }
            let newFileName = baseName + fileExt;

            // 确保新文件名没有覆盖现有文件
            const oldFilePath = path.join(folderPath, file);
            const newFilePath = path.join(folderPath, newFileName);

            if (fs.existsSync(newFilePath)) {
              reject(`文件已存在：${newFilePath}`);
              return;
            }

            // 重命名文件
            fs.renameSync(oldFilePath, newFilePath);
          } else {
            if (baseName.includes(searchStr)) {
              // 如果 replaceExt 为 false，替换文件名部分，不修改扩展名
              let newFileName =
                baseName.replace(searchStr, replaceStr) + fileExt;

              // 确保新文件名没有覆盖现有文件
              const oldFilePath = path.join(folderPath, file);
              const newFilePath = path.join(folderPath, newFileName);

              if (fs.existsSync(newFilePath)) {
                reject(`文件已存在：${newFilePath}`);
                return;
              }

              // 重命名文件
              fs.renameSync(oldFilePath, newFilePath);
            }
          }
        });

        resolve("批量替换命名成功！");
      } catch (error) {
        reject(`批量替换命名失败：${error.message}`);
      }
    });
  }
);

// // 安装依赖
// ipcMain.handle(
//   "install-dependencies",
//   async (event, folderPath, packageManager) => {
//     let installCommand: string;

//     switch (packageManager) {
//       case "yarn":
//         installCommand = "yarn";
//         break;
//       case "pnpm":
//         installCommand = "pnpm install";
//         break;
//       default:
//         installCommand = "npm install";
//         break;
//     }

//     // return executeCommand(installCommand, folderPath, useCmd);
//     return executeCommand(installCommand, folderPath);
//   }
// );

// // 启动项目
// ipcMain.handle(
//   "start-project",
//   async (event, folderPath, packageManager, command) => {
//     const startCommand = `npm run ${command}`;
//     return await executeCommand(startCommand, folderPath);
//   }
// );

// // 编译项目
// ipcMain.handle(
//   "build-project",
//   async (event, folderPath, packageManager, command) => {
//     const buildCommand = `${packageManager} run ${command}`;
//     return executeCommand(buildCommand, folderPath);
//     // return executeCommand(buildCommand, folderPath, useCmd);
//   }
// );
if (process.defaultApp) {
  if (process.argv.length >= 2) {
    app.removeAsDefaultProtocolClient("electron-vue-template");
    console.log("由于框架特殊性开发环境下无法使用");
  }
} else {
  app.setAsDefaultProtocolClient("electron-vue-template");
}
